package com.xyht.sca_s.student_manage_system.modules.assetFixedSelfInspection.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.xyht.sca_s.student_manage_system.common.commonReturn.CommonCodeEnum;
import com.xyht.sca_s.student_manage_system.common.commonReturn.CommonResult;
import com.xyht.sca_s.student_manage_system.common.commonReturn.ResponseResult;
import com.xyht.sca_s.student_manage_system.modules.asset.entity.SmsAssetCategoryManagement;
import com.xyht.sca_s.student_manage_system.modules.asset.entity.SmsAssetFixedStorage;
import com.xyht.sca_s.student_manage_system.modules.asset.mapper.SmsAssetCategoryManagementMapper;
import com.xyht.sca_s.student_manage_system.modules.asset.mapper.SmsAssetFixedStorageMapper;
import com.xyht.sca_s.student_manage_system.modules.assetFixedInventory.entity.SmsAssetInventoryDetail;
import com.xyht.sca_s.student_manage_system.modules.assetFixedSelfInspection.entity.SmsAssetSelfInspection;
import com.xyht.sca_s.student_manage_system.modules.assetFixedSelfInspection.entity.SmsAssetSelfInspectionDetail;
import com.xyht.sca_s.student_manage_system.modules.assetFixedSelfInspection.entity.SmsAssetSelfInspectionPlan;
import com.xyht.sca_s.student_manage_system.modules.assetFixedSelfInspection.entity.req.SmsAssetSelfInspectionDetailReq;
import com.xyht.sca_s.student_manage_system.modules.assetFixedSelfInspection.entity.req.SmsAssetSelfInspectionPlanFinishReq;
import com.xyht.sca_s.student_manage_system.modules.assetFixedSelfInspection.entity.resp.*;
import com.xyht.sca_s.student_manage_system.modules.assetFixedSelfInspection.mapper.SmsAssetSelfInspectionDetailMapper;
import com.xyht.sca_s.student_manage_system.modules.assetFixedSelfInspection.mapper.SmsAssetSelfInspectionMapper;
import com.xyht.sca_s.student_manage_system.modules.assetFixedSelfInspection.mapper.SmsAssetSelfInspectionPlanMapper;
import com.xyht.sca_s.student_manage_system.modules.assetFixedSelfInspection.service.SmsAssetSelfInspectionService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xyht.sca_s.student_manage_system.modules.user.entity.SmsUser;
import com.xyht.sca_s.student_manage_system.modules.user.entity.resp.SmsSearchUserResp;
import com.xyht.sca_s.student_manage_system.modules.user.mapper.SmsUserMapper;
import com.xyht.sca_s.student_manage_system.modules.websocket.service.WebSocketService;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

import static com.xyht.sca_s.student_manage_system.common.util.ParamCheckUtil.isNullOrEmpty;
import static com.xyht.sca_s.student_manage_system.modules.assetFixedSelfInspection.constant.IsCompletedConstant.COMPLETED_TYPE_NO;
import static com.xyht.sca_s.student_manage_system.modules.assetFixedSelfInspection.constant.IsCompletedConstant.COMPLETED_TYPE_YES;
import static com.xyht.sca_s.student_manage_system.modules.assetFixedSelfInspection.constant.IsUseConstant.*;

/**
 * <p>
 * 我的资产 服务实现类
 * </p>
 *
 * @author XYHT
 * @since 2024-09-28
 */
@Service
public class SmsAssetSelfInspectionServiceImpl extends ServiceImpl<SmsAssetSelfInspectionMapper, SmsAssetSelfInspection> implements SmsAssetSelfInspectionService {

    @Resource
    private SmsAssetSelfInspectionPlanMapper smsAssetSelfInspectionPlanMapper;
    @Resource
    private SmsAssetSelfInspectionMapper smsAssetSelfInspectionMapper;
    @Resource
    private SmsAssetSelfInspectionDetailMapper smsAssetSelfInspectionDetailMapper;
    @Resource
    private SmsAssetFixedStorageMapper smsAssetFixedStorageMapper;
    @Resource
    private SmsUserMapper smsUserMapper;
    @Resource
    private WebSocketService webSocketServer;
    @Resource
    private SmsAssetCategoryManagementMapper smsAssetCategoryManagementMapper;
    @Override
    public ResponseResult getMyPlanList(String userId, Integer pagNum, Integer pageSize) {
        List<SmsAssetSelfInspectionPlanResp> resp = new ArrayList<>();
        Page<SmsAssetSelfInspectionPlan> page = new Page<>(pagNum, pageSize);
        //先查是否有自查计划表开启并在时间范围内
        Date nowDate = new Date();
        List<SmsAssetSelfInspectionPlan> planList = smsAssetSelfInspectionPlanMapper.selectList(new LambdaQueryWrapper<SmsAssetSelfInspectionPlan>()
                .eq(SmsAssetSelfInspectionPlan::getIsUse, IS_USE_YES)//启用
                .lt(SmsAssetSelfInspectionPlan::getBgTime, nowDate) //开始时间小于当前时间
                .gt(SmsAssetSelfInspectionPlan::getEndTime, nowDate)); //结束时间大于当前时间
        if (planList == null || planList.size() < 1) {
            return CommonResult.success(resp);
        }
        //获取计划id
        List<String> planIdList = planList.stream().map(SmsAssetSelfInspectionPlan::getId).collect(Collectors.toList());
        //查询计划下该用户的资产自查计划id集合
        List<String> filterPlanIdList = smsAssetSelfInspectionMapper.selectList(new LambdaQueryWrapper<SmsAssetSelfInspection>()
                        .eq(SmsAssetSelfInspection::getUserId, userId)
                        .in(SmsAssetSelfInspection::getPlanId, planIdList))
                        .stream().map(SmsAssetSelfInspection::getPlanId).collect(Collectors.toList());
        if (filterPlanIdList.isEmpty()) {
            return CommonResult.success(resp);
        }

        smsAssetSelfInspectionPlanMapper.selectPage(page,new LambdaQueryWrapper<SmsAssetSelfInspectionPlan>()
                .in(SmsAssetSelfInspectionPlan::getId, filterPlanIdList)
                .orderByAsc(SmsAssetSelfInspectionPlan::getIsComplete)
                .orderByDesc(SmsAssetSelfInspectionPlan::getCreateTime));
        List<SmsAssetSelfInspectionPlanResp> list = page.getRecords().stream()
                .map(smsAssetSelfInspectionPlan -> {
                    SmsAssetSelfInspectionPlanResp resp1 = new SmsAssetSelfInspectionPlanResp();
                    BeanUtils.copyProperties(smsAssetSelfInspectionPlan, resp1);
                    resp1.setPlanId(smsAssetSelfInspectionPlan.getId());
//                    List<SmsAssetSelfInspection> inspectionList = smsAssetSelfInspectionMapper.selectList(new LambdaQueryWrapper<SmsAssetSelfInspection>()
//                            .eq(SmsAssetSelfInspection::getPlanId, smsAssetSelfInspectionPlan.getId())
//                            .eq(SmsAssetSelfInspection::getUserId, userId));
//                    if (inspectionList != null && inspectionList.size() > 0) {
//                        SmsAssetSelfInspection smsAssetSelfInspection = inspectionList.get(0);
//                        resp1.setIsComplete(smsAssetSelfInspection.getIsComplete());
//                        resp1.setCompleteTime(smsAssetSelfInspection.getCompleteTime());
//                    }else {
//                        resp1.setIsComplete(COMPLETED_TYPE_NO);
//                    }
                    return resp1;
                })
                .collect(Collectors.toList());

        return CommonResult.success(list,(int)page.getTotal());
    }

    @Override
    public ResponseResult getSelfInspectionList(Integer pagNum, Integer pageSize, String userId, String planId, String searchStr, Integer assetStatus, Integer isComplete, String assetId) {
        if (isNullOrEmpty(planId)) {
            return CommonResult.failed(CommonCodeEnum.INVALID_PARAM);
        }
        SmsAssetSelfInspectionDetailResp resp = new SmsAssetSelfInspectionDetailResp();
        //必要的校验
        SmsAssetSelfInspectionPlan smsAssetSelfInspectionPlan = smsAssetSelfInspectionPlanMapper.selectById(planId);
        if (isNullOrEmpty(smsAssetSelfInspectionPlan)) {
            return CommonResult.failed(CommonCodeEnum.ASSET_SELF_INSPECTION_PLAN_NOT_EXIST);
        }
        Integer isUse = smsAssetSelfInspectionPlan.getIsUse();
        Date bgTime = smsAssetSelfInspectionPlan.getBgTime();
        Date endTime = smsAssetSelfInspectionPlan.getEndTime();
        if (isUse == IS_USE_NO || bgTime.compareTo(new Date()) > 0 || endTime.compareTo(new Date()) < 0) {
            return CommonResult.failed(CommonCodeEnum.ASSET_SELF_INSPECTION_PLAN_NOT_START);
        }
        //校验该用户是否有自查计划
        List<SmsAssetSelfInspection> inspectionList = smsAssetSelfInspectionMapper.selectList(new LambdaQueryWrapper<SmsAssetSelfInspection>()
                .eq(SmsAssetSelfInspection::getPlanId, planId)
                .eq(SmsAssetSelfInspection::getUserId, userId));
        if (inspectionList == null || inspectionList.isEmpty()) {
            return CommonResult.failed(CommonCodeEnum.ASSET_SELF_INSPECTION_PLAN_NOT_START);
        }
        SmsAssetSelfInspection smsAssetSelfInspection = inspectionList.get(0);
        //查询该用户下的固定资产
        Page<SmsAssetSelfInspectionDetail> page = new Page<>(pagNum, pageSize);
        LambdaQueryWrapper<SmsAssetSelfInspectionDetail> selfInspectionDetailLambdaQueryWrapper = new LambdaQueryWrapper<SmsAssetSelfInspectionDetail>()
                .eq(SmsAssetSelfInspectionDetail::getSelfInspectionId,smsAssetSelfInspection.getId())
                .eq(SmsAssetSelfInspectionDetail::getUserId, userId)
                .eq(SmsAssetSelfInspectionDetail::getPlanId, planId)
                .orderByAsc(SmsAssetSelfInspectionDetail::getIsComplete)
                .orderByDesc(SmsAssetSelfInspectionDetail::getCreateTime);
        Integer count = smsAssetSelfInspectionDetailMapper.selectCount(selfInspectionDetailLambdaQueryWrapper);
        if (count < 1) {//没有固定资产
            resp.setIsHaveAssets(false);
            return CommonResult.success(resp);
        }
        if (!isNullOrEmpty(searchStr)) {
            List<String> assetIdList = smsAssetFixedStorageMapper.selectList(new LambdaQueryWrapper<SmsAssetFixedStorage>()
                    .and(i -> {
                        i.like(SmsAssetFixedStorage::getAssetName, searchStr)
                                .or()
                                .like(SmsAssetFixedStorage::getAssetModel, searchStr)
                                .or()
                                .like(SmsAssetFixedStorage::getAssetBrand, searchStr);
                    })).stream().map(SmsAssetFixedStorage::getId).collect(Collectors.toList());
            if (!assetIdList.isEmpty()) {
                selfInspectionDetailLambdaQueryWrapper.in(SmsAssetSelfInspectionDetail::getAssetId, assetIdList);
            }else {
                selfInspectionDetailLambdaQueryWrapper.eq(SmsAssetSelfInspectionDetail::getAssetId, "");
            }
        }
        if (!isNullOrEmpty(assetStatus)) {
            selfInspectionDetailLambdaQueryWrapper.eq(SmsAssetSelfInspectionDetail::getAssetStatus, assetStatus);
        }
        if (!isNullOrEmpty(assetId)) {
            selfInspectionDetailLambdaQueryWrapper.eq(SmsAssetSelfInspectionDetail::getAssetId, assetId);
        }
        if (!isNullOrEmpty(isComplete)) {
            selfInspectionDetailLambdaQueryWrapper.eq(SmsAssetSelfInspectionDetail::getIsComplete, isComplete);
        }
        smsAssetSelfInspectionDetailMapper.selectPage(page,selfInspectionDetailLambdaQueryWrapper);

        List<SmsAssetSelfInspectionDetailListResp> list = page.getRecords()
                .stream()
                .map(smsAssetSelfInspectionDetail -> {
                    SmsAssetSelfInspectionDetailListResp detailResp = new SmsAssetSelfInspectionDetailListResp();
                    SmsAssetFixedStorageInfoResp assetInfo = new SmsAssetFixedStorageInfoResp();
                    BeanUtils.copyProperties(smsAssetSelfInspectionDetail, detailResp);
                    SmsAssetFixedStorage assetFixedStorage = smsAssetFixedStorageMapper.selectById(smsAssetSelfInspectionDetail.getAssetId());
                    if (!isNullOrEmpty(assetFixedStorage)) {
                        BeanUtils.copyProperties(assetFixedStorage, assetInfo);
                    }
                    detailResp.setAssetInfo(assetInfo);
                    return detailResp;
                })
                .collect(Collectors.toList());

        return CommonResult.success(list,(int)page.getTotal());
    }

    @Override
    public ResponseResult finishOneAsset(String userId, SmsAssetSelfInspectionDetailReq req) {
        if (isNullOrEmpty(req.getPlanId(), req.getSelfInspectionId(), req.getAssetId(), req.getSelfInspectionPicture(),
                req.getAssetStatus())) {
            return CommonResult.failed(CommonCodeEnum.INVALID_PARAM);
        }
        SmsAssetSelfInspectionPlan smsAssetSelfInspectionPlan = smsAssetSelfInspectionPlanMapper.selectById(req.getPlanId());
        if (isNullOrEmpty(smsAssetSelfInspectionPlan)) {
            return CommonResult.failed(CommonCodeEnum.ASSET_SELF_INSPECTION_PLAN_NOT_EXIST);
        }
        Integer isOpenScan = smsAssetSelfInspectionPlan.getIsOpenScan();
        List<SmsAssetSelfInspectionDetail> inspectionDetailList = smsAssetSelfInspectionDetailMapper.selectList(new LambdaQueryWrapper<SmsAssetSelfInspectionDetail>()
                .eq(SmsAssetSelfInspectionDetail::getAssetId, req.getAssetId())
                .eq(SmsAssetSelfInspectionDetail::getSelfInspectionId, req.getSelfInspectionId())
                .eq(SmsAssetSelfInspectionDetail::getPlanId, req.getPlanId())
                .eq(SmsAssetSelfInspectionDetail::getUserId, userId));
        if (inspectionDetailList == null || inspectionDetailList.isEmpty()) {
            return CommonResult.failed(CommonCodeEnum.ASSET_SELF_INSPECTION_DETAIL_NOT_EXIST);
        }
        SmsAssetSelfInspectionDetail inspectionDetail = inspectionDetailList.get(0);
        inspectionDetail.setCompleteTime(new Date());
        inspectionDetail.setIsComplete(COMPLETED_TYPE_YES);
        inspectionDetail.setSelfInspectionPicture(req.getSelfInspectionPicture());
        inspectionDetail.setRemark(req.getRemark());
        if (isOpenScan != null && isOpenScan == IS_SCAN_YES) {
            if (req.getIsScanCode() == IS_SCAN_YES) {//有扫描码
                if (isNullOrEmpty(req.getAssetScanCode())) {
                    return CommonResult.failed(CommonCodeEnum.INVALID_PARAM);
                }
                if (req.getAssetId().equals(req.getAssetScanCode())) {
                    inspectionDetail.setIsScanCode(IS_SCAN_YES);
                    inspectionDetail.setSelfInspectionIsScan(COMPLETED_TYPE_YES);
                }
            }else {
                inspectionDetail.setIsScanCode(IS_SCAN_NO);
            }
        }

        smsAssetSelfInspectionDetailMapper.updateById(inspectionDetail);
//        webSocketServer.batchSend();
        return CommonResult.success();
    }

    @Override
    @Transactional
    public ResponseResult finishAll(String userId, SmsAssetSelfInspectionPlanFinishReq finishReq) {
        if (isNullOrEmpty(finishReq.getPlanId())) {
            return CommonResult.failed(CommonCodeEnum.INVALID_PARAM);
        }
        SmsAssetSelfInspectionPlan smsAssetSelfInspectionPlan = smsAssetSelfInspectionPlanMapper.selectById(finishReq.getPlanId());
        if (isNullOrEmpty(smsAssetSelfInspectionPlan)) {
            return CommonResult.failed(CommonCodeEnum.ASSET_SELF_INSPECTION_PLAN_NOT_EXIST);
        }
        String planId = smsAssetSelfInspectionPlan.getId();
        List<SmsAssetSelfInspection> inspectionList = smsAssetSelfInspectionMapper.selectList(new LambdaQueryWrapper<SmsAssetSelfInspection>()
                .eq(SmsAssetSelfInspection::getPlanId, planId)
                .eq(SmsAssetSelfInspection::getUserId, userId));
        if (inspectionList == null || inspectionList.isEmpty()) {
            return CommonResult.failed(CommonCodeEnum.ASSET_SELF_INSPECTION_PLAN_NOT_START);
        }
        SmsAssetSelfInspection smsAssetSelfInspection = inspectionList.get(0);
        if (smsAssetSelfInspection.getIsComplete() == COMPLETED_TYPE_YES) {
            return CommonResult.failed(CommonCodeEnum.ASSET_SELF_INSPECTION_ALREADY_COMPLETE);
        }
        List<SmsAssetSelfInspectionDetail> inspectionDetailList = smsAssetSelfInspectionDetailMapper.selectList(new LambdaQueryWrapper<SmsAssetSelfInspectionDetail>()
                        .eq(SmsAssetSelfInspectionDetail::getUserId, userId)
                        .eq(SmsAssetSelfInspectionDetail::getPlanId, planId)
                        .eq(SmsAssetSelfInspectionDetail::getSelfInspectionId, smsAssetSelfInspection.getId()))
                .stream()
                .filter(detail -> detail.getIsComplete() == COMPLETED_TYPE_NO)
                .collect(Collectors.toList());
        if (!inspectionDetailList.isEmpty()) {
            return CommonResult.failed(CommonCodeEnum.ASSET_SELF_INSPECTION_DETAIL_NOT_EXIST);
        }
        smsAssetSelfInspection.setCompleteTime(new Date());
        smsAssetSelfInspection.setIsComplete(COMPLETED_TYPE_YES);
        smsAssetSelfInspectionMapper.updateById(smsAssetSelfInspection);
        //修改盘点计划的状态
        smsAssetSelfInspectionPlan.setIsComplete(COMPLETED_TYPE_YES);
        smsAssetSelfInspectionPlan.setCompleteTime(new Date());
        smsAssetSelfInspectionPlanMapper.updateById(smsAssetSelfInspectionPlan);
        return CommonResult.success();
    }

    @Override
    public ResponseResult getSelfInspectionUserAllList(Integer pagNum, Integer pageSize, String planId, Integer isComplete, String selfInspectionUserName) {
        if (isNullOrEmpty(planId)) {
            return CommonResult.failed(CommonCodeEnum.INVALID_PARAM);
        }
        Page<SmsAssetSelfInspection> page = new Page<>(pagNum, pageSize);
        LambdaQueryWrapper<SmsAssetSelfInspection> lambdaQueryWrapper = new LambdaQueryWrapper<SmsAssetSelfInspection>()
                .eq(SmsAssetSelfInspection::getPlanId, planId)
                .orderByAsc(SmsAssetSelfInspection::getIsComplete)
                .orderByDesc(SmsAssetSelfInspection::getCreateTime);
        if (!isNullOrEmpty(isComplete)) {
            lambdaQueryWrapper.eq(SmsAssetSelfInspection::getIsComplete, isComplete);
        }
        if (!isNullOrEmpty(selfInspectionUserName)) {
            List<String> userIdList = smsUserMapper.selectList(new LambdaQueryWrapper<SmsUser>()
                            .like(SmsUser::getRealName, selfInspectionUserName))
                    .stream()
                    .map(SmsUser::getId)
                    .collect(Collectors.toList());
            if (!userIdList.isEmpty()) {
                lambdaQueryWrapper.in(SmsAssetSelfInspection::getUserId, userIdList);
            }else {
                lambdaQueryWrapper.in(SmsAssetSelfInspection::getUserId, "");
            }
        }
        smsAssetSelfInspectionMapper.selectPage(page, lambdaQueryWrapper);
        List<SmsAssetSelfInspectionResp> list = page.getRecords()
                .stream()
                .map(smsAssetSelfInspection -> {
                    SmsAssetSelfInspectionResp resp = new SmsAssetSelfInspectionResp();
                    SmsSearchUserResp selfInspectionUserInfo = new SmsSearchUserResp();
                    BeanUtils.copyProperties(smsAssetSelfInspection, resp);
                    //盘点信息
                    SmsUser smsUser = smsUserMapper.selectById(smsAssetSelfInspection.getUserId());
                    if (!isNullOrEmpty(smsUser)) {
                        BeanUtils.copyProperties(smsUser, selfInspectionUserInfo);
                    }
                    resp.setSelfInspectionUserInfo(selfInspectionUserInfo);
                    return resp;
                })
                .collect(Collectors.toList());
        return CommonResult.success(list, (int) page.getTotal());
    }

    @Override
    public ResponseResult getAppointSelfInspectionAllList(Integer pagNum, Integer pageSize, String planId, Integer isComplete, String userId, Integer assetStatus) {
        if (isNullOrEmpty(planId,userId)) {
            return CommonResult.failed(CommonCodeEnum.INVALID_PARAM);
        }
        Page<SmsAssetSelfInspectionDetail> page = new Page<>(pagNum, pageSize);
        LambdaQueryWrapper<SmsAssetSelfInspectionDetail> lambdaQueryWrapper = new LambdaQueryWrapper<SmsAssetSelfInspectionDetail>()
                .eq(SmsAssetSelfInspectionDetail::getPlanId, planId)
                .eq(SmsAssetSelfInspectionDetail::getUserId, userId)
                .orderByAsc(SmsAssetSelfInspectionDetail::getIsComplete)
                .orderByDesc(SmsAssetSelfInspectionDetail::getCreateTime);
        if (!isNullOrEmpty(isComplete)) {
            lambdaQueryWrapper.eq(SmsAssetSelfInspectionDetail::getIsComplete, isComplete);
        }
        if (!isNullOrEmpty(assetStatus)) {
            lambdaQueryWrapper.eq(SmsAssetSelfInspectionDetail::getAssetStatus, assetStatus);
        }
        smsAssetSelfInspectionDetailMapper.selectPage(page, lambdaQueryWrapper);
        List<SmsAssetSelfInspectionDetailListResp> list = page.getRecords()
                .stream()
                .map(smsAssetSelfInspectionDetail -> {
                    SmsAssetSelfInspectionDetailListResp resp = new SmsAssetSelfInspectionDetailListResp();
                    BeanUtils.copyProperties(smsAssetSelfInspectionDetail, resp);
                    SmsAssetFixedStorageInfoResp assetInfo = new SmsAssetFixedStorageInfoResp();
                    SmsAssetFixedStorage assetFixedStorage = smsAssetFixedStorageMapper.selectById(smsAssetSelfInspectionDetail.getAssetId());
                    if (!isNullOrEmpty(assetFixedStorage)) {
                        BeanUtils.copyProperties(assetFixedStorage, assetInfo);
                        //类别
                        SmsAssetCategoryManagement smsAssetCategoryManagement = smsAssetCategoryManagementMapper.selectById(assetFixedStorage.getAssetCategory());
                        if (!isNullOrEmpty(smsAssetCategoryManagement)) {
                            assetInfo.setAssetCategoryName(smsAssetCategoryManagement.getCategoryName());
                            assetInfo.setAssetCategory(smsAssetCategoryManagement.getId());
                        }
                    }
                    resp.setAssetInfo(assetInfo);
                    return resp;
                })
                .collect(Collectors.toList());
        return CommonResult.success(list, (int) page.getTotal());
    }
}
